﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Xml;
using System.Xml.XPath;
using GianosNET.Common.Classes;
using GianosNET.Services.CronSVC.classes;
using SQLPXBase;

namespace GianosNET.Services.CronSVC
{
    public class CronSVC : LoopingService
    {
        private const string svcName = "CRON SERVICE";
        private const string vNum = "1.0";

        private Dictionary<string, Task> tasks = new Dictionary<string, Task>();

        public CronSVC(ServerInfo info) : this(false, info)
        {
        }

        public CronSVC(bool enableAutoStart, ServerInfo info) : this(new Hashtable(), null, enableAutoStart, info)
        {
        }

        public CronSVC(Hashtable config, ProxyManager<sqlStatus> statusProxyMgr, bool enableAutoStart, ServerInfo info)
            : base(svcName, vNum, config, statusProxyMgr, enableAutoStart, info)
        {
        }

        protected override void CustomJobExecution(BackgroundWorker job)
        {
            XPathNavigator nav = null;

            // Carica il file esterno di cofigurazione dei servizi schedulati
            if (config != null && config.Count > 0)
            {
                XmlDocument doc = new XmlDocument();

                try
                {
                    doc.Load(config["configFile"].ToString());
                    nav = doc.CreateNavigator();
                }
                catch
                {
                    throw new Exception("Impossibile leggere il file di configurazione");
                }

                // Aggiorna la lista dei task (non richiede il riavvio del servizio)
                XPathNodeIterator iterator = nav.Select("/tasks/task");
                foreach (XPathNavigator task in iterator)
                {
                    Task tmp = Task.CreateInstance(task);

                    if (!tasks.ContainsKey(tmp.ID))
                    {
                        ServerInfo.EnqueueInLog(MainLogId,
                                                string.Format(
                                                    "[{0}] - Aggiunto nuovo task: {1} (prox. esecuzione: {2})",
                                                    DateTime.Now.ToString("dd/MM HH:mm:ss"), tmp.ID,
                                                    tmp.NextExecution.ToString("dd/MM HH:mm:ss")));
                        tasks.Add(tmp.ID, tmp);
                    }
                    else
                    {
                        if (tasks[tmp.ID] != null)
                        {
                            tmp.LastExecution = tasks[tmp.ID].LastExecution;
                            tmp.SetNextExecution(tasks[tmp.ID].NextExecution);
                        }
                        tasks[tmp.ID] = tmp;
                    }
                }
            }

            foreach (Task t in tasks.Values)
            {
                if (t.Enabled && t.TimeForExecution)
                {
                    ServerInfo.EnqueueInLog(MainLogId,
                                            string.Format("[{0}] - Executing: {1}",
                                                          DateTime.Now.ToString("dd/MM HH:mm:ss"), t.ID));
                    string res = t.Execute();
                    if (!string.IsNullOrWhiteSpace(res))
                        ServerInfo.EnqueueInLog(MainLogId,
                                                string.Format("[{0}] - {1}", DateTime.Now.ToString("dd/MM HH:mm:ss"),
                                                              res));
                }
            }
        }
    }
}